using TicTacToe.Core;
using Newtonsoft.Json.Linq;

namespace _3DTicTacToe.Net
{
    sealed class NetGame : TicTacToeGame
    {
        private readonly Connection _connection;

        public Player LocalPlayer { get; private set; }
        public Player RemotePlayer { get; private set; }

        public delegate void ChatMsgReceivedDlg(string message);
        public event ChatMsgReceivedDlg OnChatMessageReceived;

        public void Shutdown()
        {
            _connection.Shutdown();
        }

        public void SendChatMessage(string message)
        {
            var msg = new NetMessage("chat", new JObject {{"Message", message}});
            _connection.SendMessage(msg);
        }

        public NetGame(Player hostPlayer, Player clientPlayer, Connection connection)
            : base(hostPlayer, clientPlayer)
        {
            _connection = connection;
            _connection.OnGameTurnReceived += TurnReceived;
            _connection.OnChatMessageReceived += ChatMessageReceived;

            OnGameOver += NetGame_OnGameOver;
            OnTurn += NetGame_OnTurn;

            LocalPlayer = (_connection.IsHost) ? PlayerOne : PlayerTwo;
            RemotePlayer = (LocalPlayer == PlayerOne) ? PlayerTwo : PlayerOne;
        }

        void ChatMessageReceived(NetMessage message)
        {
            if (OnChatMessageReceived != null)
                OnChatMessageReceived((string) message.Content["Message"]);
        }

        void TurnReceived(NetMessage message)
        {
            var turn = Serialization.DeserializeTurn(message.Content);
            MakeTurn(turn);
        }

        void NetGame_OnTurn(object sender, TurnEventArgs e)
        {
            if (e.Turn.Player != LocalPlayer) return;

            var turnObj = e.Turn.Serialize();
            var msg = new NetMessage("turn", turnObj);
            _connection.SendMessage(msg);
        }

        void NetGame_OnGameOver(object sender, GameOverEventArgs e)
        {
            if (_connection.IsHost) // HACK!!
                Shutdown();
        }
    }
}